package main

import (
	"fmt"
	"os"
	"raftique/pkg/config"
	"raftique/pkg/log"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

const Version = "0.0.1"

var (
	cfgFile     string
	showVersion bool
	cfg         config.ServerConfig
)

func init() {
	rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of raftique")
	rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of raftique")

	cobra.OnInitialize(initConfig)
}

func initConfig() {
	if cfgFile != "" {
		// 使用指定的配置文件
		viper.SetConfigFile(cfgFile)
	} else {
		fmt.Println("use default config")
		// 查找默认配置文件目录
		home, err := os.UserHomeDir()
		if err != nil {
			fmt.Println("Error:", err)
			os.Exit(1)
		}

		// 设置默认配置文件搜索路径
		viper.AddConfigPath(home)
		viper.AddConfigPath(".")
		viper.AddConfigPath("/etc/raftique")
		viper.SetConfigName("config")
		viper.SetConfigType("yaml")
	}

	// 读取环境变量
	viper.AutomaticEnv()

	// 读取配置文件
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())

		// 将配置文件中的值绑定到配置结构体
		if err := viper.Unmarshal(&cfg); err != nil {
			fmt.Println("Error parsing config:", err)
			os.Exit(1)
		}
	} else {
		// 配置文件不存在或无法读取时不终止，使用默认值或命令行参数
		if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
			fmt.Println("Error reading config file:", err)
		}
	}
}

var rootCmd = &cobra.Command{
	Use:   "raftique",
	Short: "raftique is a implementation of raft protocol based on go",
	RunE: func(cmd *cobra.Command, args []string) error {
		if showVersion {
			fmt.Printf("raftique version %s\n", Version)
			return nil
		}

		// 验证日志配置
		if cfg.Log.Level == "" {
			cfg.Log.Level = "info" // 默认日志级别
		}

		if cfg.Log.To == "" {
			cfg.Log.To = "console" // 默认日志输出到控制台
		}

		if cfg.Log.MaxDays <= 0 {
			cfg.Log.MaxDays = 30 // 默认日志保留30天
		}

		if cfg.Log.DisablePrintColor {
			cfg.Log.DisablePrintColor = true // 默认不启用彩色日志
		}

		// 使用完整配置启动服务器
		if err := runServer(&cfg); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		return nil
	},
}

func runServer(cfg *config.ServerConfig) error {
	log.InitLogger(cfg.Log.To, cfg.Log.Level, int(cfg.Log.MaxDays), cfg.Log.DisablePrintColor)

	return nil
}
